#include <iostream>
#include <cstdio>
#include <string>
#include <ctype.h>
#include "Sock.hpp"
#include "Err.hpp"
#include "Protocol.hpp"
using namespace pr;
//./calculatorclient serverip serverport
void Usage(std::string u)
{
    std::cout << "Usage:\n\t" << u << " serverip serverport" << std::endl;
}

enum
{
    Left = 0,
    Right,
    OP
};

// 将“1 + 2”  --> _x = 1 _y = 2 _op = +
Request ParseLine(std::string str)
{
    std::string left, right;
    char op;
    int statue = Left;
    int i = 0;
    while (i < str.size())
    {
        switch (statue)
        {
        case Left:
            if(isdigit(str[i]))
            {
                left.push_back(str[i++]);
            }else
            {
                statue = OP;
            }
            break;
        case OP:
            op = str[i++];
            statue = Right;
            break;
        case Right:
            right.push_back(str[i++]);
            break;
        }
    }
    Request req;
    req._x = std::stoi(left);
    req._y = std::stoi(right);
    req._op = op;
    return req;
}
int main(int argv, char *argc[])
{
    if (argv != 3)
    {
        Usage(argc[0]);
        exit(USAGE_ERROR);
    }
    std::string serverip = argc[1];
    uint16_t serverport = atoi(argc[2]);
    Sock sock;
    sock.Socket();
    int cnt = 5;
    while (sock.Connect(serverip, serverport) < 0)
    {
        if (cnt == 0)
            break;
        std::cout << "连接失败，正在重连...重连的剩余次数:" << cnt-- << std::endl;
    }
    if (cnt <= 0)
    {
        std::cout << "连接失败" << std::endl;
        sock.Close();
        exit(CONNECT_ERROR);
    }
    std::string Inffer;
    while (true)
    {
        std::cout << "Enter#";
        std::string line;
        std::getline(std::cin, line);
        Request request = ParseLine(line);
        // std::cout << "data1#";
        // std::cin >> request._x;
        // std::cout << "data2#";
        // std::cin >> request._y;
        // std::cout << "op#";
        // std::cin >> request._op;
        // std::cout << "test:" << request._x << request._op << request._y << std::endl;

        // 1.将请求数据进行序列化操作
        std::string sendStr;
        request.Serialize(&sendStr);
        // 2.添加报头
        sendStr = AddHeader(sendStr);
        // 3.发送数据
        send(sock.Fd(), sendStr.c_str(), sendStr.size(), 0);
    START:
        // 1.获取完整的单个的数据报
        std::string packet;
        int n = ReadPacket(sock.Fd(), Inffer, &packet);

        if (n == -1)
        {
            break;
        }
        else if (n == 0)
            goto START;
        else
        {
            // 2.去掉报头
            packet = RemoveHeader(packet, n);
            // 3.对结果进行反序列
            Response response;
            response.Deserialize(packet);
            std::cout << "result:" << response._result << "[code:" << response._code << "]" << std::endl;
        }
    }
    sock.Close();
    return 0;
}